<?php
	/**
	 * Component structure
	 * 
	 * Implements the basic structure of a very generic component for the krome
	 * system.
	 * 
	 * @author     Brandon R. Stoner <brandon.stoner@gmail.com>
	 * @copyright  Copyright 2008, Monokromatic Inc.
	 * @package    Components
	 * @subpackage Core
	 */

	/**
	 * Component object.
	 *
	 * Implementation of the basic structure of a component for the Krome engine.
	 *	 
	 * @author     Brandon R. Stoner <brandon.stoner@gmail.com>
	 * @copyright  Copyright 2008, Monokromatic Inc.
	 * @package    Components
	 * @subpackage Core
	 **/			 
	abstract class IKromeComponent extends IKromeBase
	{
		/**
		 * "Friendly" name for this object.
		 **/		 		
		public    $name      = 'Krome Component';

		/**
		 * References the component manager that instantiated this component, if
		 * the component was instantiated by one.
		 * @see CKromeComponentManager		 
		 * @var object		 		 
		 **/		 		
		protected $manager   = null;

		/**
		 * Defines the functional abilities that this component provide.
		 * @var array		 
		 **/
		protected $abilities = Array();

		/**
		 * True if this component is currently enabled.
		 * @var bool		 		 
		 **/		 		
		protected $enabled   = true;

		/**
		 * True if this component is finished doing whatever it's supposed to do.
		 * @var bool		 
		 **/		 		
		protected $finished  = false;

		/**
		 * Used for registering abilities with this component
		 **/		 		
		public function Register() { }

		/**
		 * Used for cleaning up any resources that have been allocated for the use
		 * of this component.		 
		 **/		 		
		abstract public function Cleanup();

		/**
		 * Set our component manager to whatever object is passed to the method, and
		 * call Register().
		 * @see CKromeComponentManager
		 *		 		 
		 * @param object $manager Reference to our component manager, if one exists. 		 		 		  
		 **/
		public function __construct( $manager = null )
		{
			$this->manager = $manager;
			$this->Register();
		}

		/**
		 * Calls the Cleanup() function.
		 **/		 		
		public function __destroy()
		{
			$this->Cleanup();
		}

		/**
		 * Returns a reference to this component's manager
		 * @return object Reference to this component's manager
		 **/		 		
		public function GetManager()
		{
			return $this->manager;
		}

		/**
		 * Registers a single ability to this component, so that the manager knows
		 * that it is available through this object. Can also be passed an array
		 * of abilities, or an array of arrays of abilities, etc.		 
		 * @param string|array $ability The ability that we are able to provide
		 * @param bool $enabled False if this feature can't be provided any more
		 **/		 		
		public function RegisterAbility( $ability, $enabled=true )
		{
			if ( is_array($ability) )
			{
				foreach ($ability as $val)
				{
					$this->RegisterAbility($val, $enabled);
				}
			}
			else
			{
				$this->abilities[$ability] = $enabled;
			}
		}

		/**
		 * Completely remove an ability from the list of functions that this
		 * component is able to provide.
		 * @return bool False if this ability didn't exist in the first place		 		 
		 **/
		public function RemoveAbility( $ability )
		{
			$retVal = false;

			if ( $this->HasAbility($ability) )
			{
				unset( $this->abilities[$ability] );
				$retVal = true;
			}

			return $retVal;
		}

		/**
		 * Returns true if the requested ability is available via this component
		 * @param string $ability The ability that we are requesting		 
		 * @return bool True if the requested ability is available via this object		 
		 **/		 		
		public function HasAbility( $ability )
		{
			$retVal = false;

			if ( isset($this->abilities[$ability]) && $this->abilities[$ability] !== false )
			{
				$retVal = $this->abilities[$ability];
			}

			return $retVal;
		}

		/**
		 * Returns false if this component isn't enabled
		 * @return bool False if this component isn't enabled
		 **/
		public function IsEnabled()
		{
			return $this->enabled;
		}

		/**
		 * Returns true if this component is NOT enabled, and it IS finished
		 * processing. Any completely finished process should be disabled. Some
		 * component managers may destroy the component if this returns true.
		 * @see IKromeComponent::__destroy()
		 * @return bool True if the component is not enabled, and is done processing		 
		 **/		 		
		public function IsFinished()
		{
			return ($this->enabled != ($this->finished == true) );
		}

		/**
		 * Disables the component and marks it as finished processing.
		 * @note 		 
		 **/		 		
		public function Kill()
		{
			$this->enabled  = false;
			$this->finished = true;
		}
	}
?>
